package cqrtplm.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.hustcad.plm.pdm.common.model.dto.search.SearchConditionDTO;
import com.hustcad.plm.pdm.common.model.vo.search.ResultEntityVO;
import com.hustcad.plm.pdm.common.service.search.TyplmCommonSearchService;
import com.hustcad.plm.pdm.doc.vo.DocDetails;
import com.hustcad.plm.pdm.ec.module.dto.ECObjData;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowChgFormView;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowObject;
import com.hustcad.plm.pdm.flowbusiness.model.entity.WorkFlowObjectPackage;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartService;
import com.hustcad.plm.pdm.partbom.dto.PartBomTree;
import com.hustcad.plm.pdm.partbom.dto.PartUsageLink;
import com.hustcad.plm.pdm.partbom.service.TyplmPartBomService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartRelObjectService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartService;
import com.hustcad.plm.pdm.partbom.vo.PartBomTreeByFilterVO;
import com.hustcad.plm.pdm.partbom.vo.PartDetailsVO;
import com.hustcad.plm.pdm.partbom.vo.TyPartAllVO;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainerView;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerService;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.part.PartDO;
import com.ty.basic.entity.part.PartUsageLinkDO;
import com.ty.basic.vo.AttributeVO;
import cqrtplm.common.CommonService;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.constant.RTPlmConstant;
import cqrtplm.dto.EncodedMasterDataDTO;
import cqrtplm.mapper.RTChangeMapper;
import cqrtplm.service.SapIntegrityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SapIntegrityServiceImpl implements SapIntegrityService {
    @Resource
    private CommonService commonService;
    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;
    @Resource
    private TyplmPartService typlmPartService;
    @Resource
    private TyplmWorkFlowContainerService typlmWorkFlowContainerService;
    @Resource
    private TyplmCommonSearchService typlmCommonSearchService;
    @Resource
    private TyplmPartRelObjectService typlmPartRelObjectService;
    @Resource
    private RTChangeMapper rtChangeMapper;
    @Resource
    private TyplmPdmPartService typlmPdmPartService;
    @Resource
    private TyplmPartBomService typlmPartBomService;
    @Value("${sap.material.url}")
    private String materialSapUrl;
    @Value("${sap.bom.url}")
    private String bomSapUrl;
    @Value("${sap.dev.code.url}")
    private String sapDevCodeUrl;
    @Value("${sap.name}")
    private String sapName;
    @Value("${sap.password}")
    private String sapPassword;

    private static final List<String> attributeVOS = Arrays.asList("", "", "");
    //工厂视图
//    @Value("${factory.view}")
//    private String factoryView;

    private static String WERKS = null;

    @Override
    public void sendEncodedMasterData(BigInteger workFlowContainerId) {
        List<IdentifierEntity> flowObjEntityList = commonService.getFlowObjListByWorkFlowContainer(workFlowContainerId);
        List<BigInteger> partOidList = flowObjEntityList.stream().filter(identifierEntity -> TableTypeConstrant.TY_PART_OTYPE.equals(identifierEntity.getOtype())).map(IdentifierEntity::getOid).collect(Collectors.toList());
        List<TyPartAllVO> tyPartAllVOS = typlmPartService.queryPartAllVOList(partOidList);
        Map<String, List<AttributeVO>> attrValueByOidAndKeys = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(partOidList, TableTypeConstrant.TY_PART_OTYPE, attributeVOS);
        List<EncodedMasterDataDTO> sendCodeDTOS = new ArrayList<>();
        for (TyPartAllVO tyPartAllVO : tyPartAllVOS) {
            EncodedMasterDataDTO sendCodeDTO = new EncodedMasterDataDTO();
            sendCodeDTO.setMatnr(tyPartAllVO.getObjectNumber());
            sendCodeDTO.setMaktx(tyPartAllVO.getName());
            sendCodeDTO.setMeins(tyPartAllVO.getDefaultunitkey());
        }
    }

    @Override
    public void bomAndMaterialsToSAP(BigInteger workFlowContainerId, String type) {
        // 检查 workFlowContainerId 是否为 null
        if (workFlowContainerId == null) {
            log.warn("workFlowContainerId 为 null，跳过成品 BOM 和物料清单下发 SAP 操作");
            return;
        }
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(workFlowContainerId);

        // 创建集合用于累积物料和BOM数据
        List<Map<String, Object>> allMaterialItems = new ArrayList<>();
        List<Map<String, Object>> allBomItems = new ArrayList<>();

        if (workFlowContainerView instanceof FlowChgFormView) {
            log.info("当前流程属于变更流程/发布流程");
            FlowChgFormView flowChgFormView = (FlowChgFormView) workFlowContainerView;
            // 检查 getChgFormVO 是否为 null
            if (flowChgFormView.getChgFormVO() != null) {
                List<ECObjData> flowObjectList = flowChgFormView.getChgFormVO().getEcAffectVOS();
                if(CollUtil.isNotEmpty(flowObjectList)){
                    for (ECObjData ecObjData : flowObjectList) {
                        String viewName = ecObjData.getViewName();
                        String typeDefName = ecObjData.getTypeDefName();
                        //所有工厂视图 factoryView
//                        if (StringUtils.isNotBlank(factoryView)) {
//                            if (StringUtils.isNotBlank(viewName) && factoryView.contains(viewName)) {
                                if ("成品码".equals(typeDefName)) {
                                    PartBomTreeByFilterVO partBomTreeByFilterVO = commonService.queryChildParts(ecObjData.getNumber(), ecObjData.getOid().toString(), viewName, false, "RELEASED", "N");

                                    //重置机组成品码的工厂，用于与动力成品码比较
                                    WERKS = "";
                                    // 收集物料数据
                                    if ("material".equals(type) || "all".equals(type)) {
                                        List<Map<String, Object>> materialItems = parsePartBom(partBomTreeByFilterVO);
                                        if (materialItems != null && !materialItems.isEmpty()) {
                                            allMaterialItems.addAll(materialItems);
                                        }
                                    }
                                    // 收集BOM数据
                                    if ("bom".equals(type) || "all".equals(type)) {
                                        List<Map<String, Object>> bomItems = TraverseTheBOMTree(String.valueOf(ecObjData.getOid()), ecObjData.getOtype(), viewName);
                                        if (bomItems != null && !bomItems.isEmpty()) {
                                            allBomItems.addAll(bomItems);
                                        }
                                    }
                                }else if("物料码".equals(typeDefName)){
                                    PartBomTreeByFilterVO partBomTreeByFilterVO = commonService.queryChildParts(ecObjData.getNumber(), ecObjData.getOid().toString(), viewName, false, "RELEASED", "N");
                                    // 收集物料数据
                                    if ("material".equals(type) || "all".equals(type)) {
                                        List<Map<String, Object>> materialItems = parsePartBom(partBomTreeByFilterVO);
                                        if (materialItems != null && !materialItems.isEmpty()) {
                                            allMaterialItems.addAll(materialItems);
                                        }
                                    }
                                }
//                            }
//                        }
                    }
                }
            }
        } else if (workFlowContainerView instanceof WorkFlowObjectPackage) {
            WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
            List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();
            for (FlowObject flowObject : flowObjectList) {
                String viewName = flowObject.getRefObjectView();
                String typeDefName = flowObject.getType();
                //所有工厂视图 factoryView
//                if (StringUtils.isNotBlank(factoryView)) {
//                    if (StringUtils.isNotBlank(viewName) && factoryView.contains(viewName)) {
                        if ("成品码".equals(typeDefName)) {
                            PartBomTreeByFilterVO partBomTreeByFilterVO = commonService.queryChildParts(flowObject.getRefObjectNumber(), flowObject.getRefObjectOid().toString(), viewName, false, "RELEASED", "N");
                            // 收集物料数据
                            if ("material".equals(type) || "all".equals(type)) {
                                List<Map<String, Object>> materialItems = parsePartBom(partBomTreeByFilterVO);
                                if (materialItems != null && !materialItems.isEmpty()) {
                                    allMaterialItems.addAll(materialItems);
                                }
                            }
                            // 收集BOM数据
                            if ("bom".equals(type) || "all".equals(type)) {
                                List<Map<String, Object>> bomItems = TraverseTheBOMTree(String.valueOf(flowObject.getRefObjectOid()), flowObject.getOtype(), viewName);
                                if (bomItems != null && !bomItems.isEmpty()) {
                                    allBomItems.addAll(bomItems);
                                }
                            }
                        }else if("物料码".equals(typeDefName)){
                            PartBomTreeByFilterVO partBomTreeByFilterVO = commonService.queryChildParts(flowObject.getRefObjectNumber(), flowObject.getRefObjectOid().toString(), viewName, false, "RELEASED", "N");
                            // 收集物料数据
                            if ("material".equals(type) || "all".equals(type)) {
                                List<Map<String, Object>> materialItems = parsePartBom(partBomTreeByFilterVO);
                                if (materialItems != null && !materialItems.isEmpty()) {
                                    allMaterialItems.addAll(materialItems);
                                }
                            }
                        }
//                    }
//                }
            }
        }

        // 统一下发物料主数据
        if ("material".equals(type) || "all".equals(type)) {
            //去重处理
            List<Map<String, Object>>  distMaterialItems=allMaterialItems.stream().collect(Collectors.collectingAndThen(
                    Collectors.toMap(e -> Arrays.asList(e.get("MATNR"), e.get("WERKS")),e -> e,
                            (existing, replacement) -> existing
                    ),map -> new ArrayList<>(map.values()))
            );
            if (!allMaterialItems.isEmpty()) {
                sendMaterialData(distMaterialItems);
            } else {
                log.info("没有需要下发的物料主数据");
            }
        }

        // 统一下发BOM数据
        if ("bom".equals(type) || "all".equals(type)) {
            if (!allBomItems.isEmpty()) {
                sendBomData(allBomItems);
            } else {
                log.info("没有需要下发的BOM数据");
            }
        }
    }

    // 发送物料主数据
    private void sendMaterialData(List<Map<String, Object>> materialItems) {
        Map<String, List<Map<String, Object>>> inTab = new HashMap<>();
        inTab.put("item", materialItems);
        Map<String, Object> requestBodyMap = new HashMap<>();
        requestBodyMap.put("IN_TAB", inTab);
        log.info("下发物料主数据：" + requestBodyMap);
        String body = requestBodyMap.toString();
        requestSAP(requestBodyMap, materialSapUrl);
    }

    // 发送BOM数据
    private void sendBomData(List<Map<String, Object>> bomItems) {
        Map<String, List<Map<String, Object>>> inTab = new HashMap<>();
        inTab.put("item", bomItems);
        Map<String, Object> requestBodyMap = new HashMap<>();
        requestBodyMap.put("IN_TAB", inTab);
        log.info("下发BOM数据：" + requestBodyMap);
        String body = requestBodyMap.toString();
        requestSAP(requestBodyMap, bomSapUrl);
    }

    private List<Map<String, PartDetailsVO>> queryChildPart(List<Map<String, PartDetailsVO>> list, String oid, String otype, String viewName) {
        if (StringUtils.isNotBlank(oid) && StringUtils.isNotBlank(otype)) {
            PartDetailsVO parentDetailVO = this.typlmPartService.queryPartDetails(new BigInteger(oid), otype);
            TyPartAllVO partAllVO=this.typlmPartService.queryPartAllVO(new BigInteger(oid), otype);
            List<PartDO> partDOS = this.rtChangeMapper.queryChildPart(oid, viewName);
            for (PartDO partDO : partDOS) {
                Map<String, PartDetailsVO> map = new HashMap<>();
                map.put("parent", parentDetailVO);
                BigInteger childOid = partDO.getOid();
                String childOType = partDO.getOtype();
                PartDetailsVO detailsVO = this.typlmPartService.queryPartDetails(childOid, childOType);
                map.put("child", detailsVO);
                list.add(map);
                queryChildPart(list, childOid.toString(), childOType, viewName);
            }
        }
        return list;
    }

    // 修改返回类型为 List<Map<String, Object>>
    private List<Map<String, Object>> parsePartBom(PartBomTreeByFilterVO partBomTreeByFilterVO) {
        // 检查 partBomTreeList 是否为 null
        List<PartBomTree> partBomTreeList = Optional.ofNullable(partBomTreeByFilterVO.getPartBomTreeList()).orElse(Collections.emptyList());
        // 移除未使用的列表
        List<Map<String, Object>> itemMapList = new ArrayList<>();
        for (PartBomTree partBomTree : partBomTreeList) {
            Map<String, List<String>> map = partBomTree.getIbaAttributeMap();
            if (map != null && !map.isEmpty()) {
                if (map.containsKey(RTPlmConstant.ALREADYSENDSAP)) {
                    String hasSendSAP = map.get(RTPlmConstant.ALREADYSENDSAP).toString();
                    //已下发SAP,跳过
                    if ("是".equals(hasSendSAP) || "Y".equals(hasSendSAP))
                        continue;
                }
            }
            String name = partBomTree.getTypeInnerName() != null ? partBomTree.getTypeInnerName() : partBomTree.getTypeName();
            switch (name) {
                case "ProductCode":
                case "成品码":
                    List<Map<String, Object>> maps = parseFinishedProductCode(partBomTree);
                    itemMapList.addAll(maps);
                    break;
                case "Standard":
                case "标准件":
                    Map<String, Object> stringObjectMap1 = parseMaterialCodeAndStandardComponent(partBomTree, "Z003", "标准件");
                    itemMapList.add(stringObjectMap1);
                    break;
                case "MaterialCode":
                case "物料码":
                    Map<String, Object> stringObjectMap2 = parseMaterialCodeAndStandardComponent(partBomTree, "Z002", "零部件");
                    itemMapList.add(stringObjectMap2);
                    break;
                default:
                    break;
            }
        }
        return itemMapList; // 返回解析结果而不直接发送
    }

    private void requestSAP(Map<String, Object> requestBodyMap, String sapUrl) {
        String auth = sapName + ":" + sapPassword;
        // 进行 Base64 编码
        String encodedAuth = Base64.encode(auth);
        // 构建 Authorization 请求头的值
        String authHeader = "Basic " + encodedAuth;
        String body = JSON.toJSONString(requestBodyMap);
        HttpResponse response = HttpRequest.post(sapUrl).header("Content-Type", "application/json").header("Authorization", authHeader) // 添加 Basic 认证头
                .body(JSON.toJSONString(requestBodyMap)).execute();
        // 处理响应
        if (response.isOk()) {
            String result = response.body();
            log.info("请求成功，响应结果：{}", result);
        } else {
            log.error("请求失败，状态码：{}", response.getStatus());
            log.error("请求失败，失败原因：{}", response.body());
            throw RTErrorCodeEnum.SEND_SAP_EXCEPTION.getException("下发sap失败");
        }
    }

    private Map<String, Object> parseMaterialCodeAndStandardComponent(PartBomTree partBomTree, String mtart, String mtbez) {
        Map<String, Object> itemMap = new HashMap<>();
        // 物料码从对应的图样代号中获取
        PartDetailsVO partDetailsVODrawing = null;
        if ("Z002".equals(mtart)) {
            String baseObjectNumber = extractBaseObjectNumber(partBomTree.getObjectNumber());
            partDetailsVODrawing = queryAttributeOfDrawingCode(baseObjectNumber);
            itemMap.put("ZTH", baseObjectNumber);
        } else {
            partDetailsVODrawing = queryAttributeOfDrawingCode(partBomTree.getObjectNumber());
            itemMap.put("ZTH", partBomTree.getObjectNumber());
        }
        PartDetailsVO partDetailsVO = this.typlmPartService.queryPartDetails(new BigInteger(partBomTree.getPartoid()), partBomTree.getPartotype());

        if (partDetailsVO != null) {
            itemMap.put("MATNR", partDetailsVO.getObjectNumber());
            // 添加物料名称（MAKTX）
            itemMap.put("MAKTX", partDetailsVO.getName());
            // 添加物料类型
            itemMap.put("MTART", mtart);
            itemMap.put("MTBEZ", mtbez);
            // TODO 单位
            itemMap.put("MEINS", "PC");
            itemMap.put("GEWEI", "KG");
            itemMap.put("VOLEH", "M3");
            // 添加工厂
            itemMap.put("WERKS", partDetailsVO.getView());
            //添加成品类别
            itemMap.put("ZCPLB", "");
            //添加采购类型
            itemMap.put("BESKZ", "");
            // 添加描述
            itemMap.put("ZMAKTX", partDetailsVO.getDescription() != null ? partDetailsVO.getDescription() : "");
        }
        // 处理 partDetailsVODrawing 可能为 null 的情况
        if (partDetailsVODrawing != null) {
            Map<String, List<String>> ibaAttributeMap = partDetailsVODrawing.getIbaAttributeMap();
            if (ibaAttributeMap != null) {
                // 添加机型
                putValueIfNotEmpty(itemMap, "ZJX", ibaAttributeMap.get("productType"));
                // 添加开发令
                putValueIfNotEmpty(itemMap, "ZKFL", ibaAttributeMap.get(RTPlmConstant.DevelopmentOrder));
                //是否无需出图
                List<String> noDrawingsRequired = ibaAttributeMap.get("NoDrawingsRequired");
                if (noDrawingsRequired != null && !noDrawingsRequired.isEmpty()) {
                    if ("是".equals(noDrawingsRequired.get(0))) {
                        boolean graphicDocuments = checkIfThereAreAnyGraphicDocuments(new BigInteger(partDetailsVODrawing.getOid()));
                        itemMap.put("ZSJTZ", graphicDocuments ? "Y" : "N");
                    } else {
                        itemMap.put("ZSJTZ", "NA");
                    }
                }
            }
        }
        return itemMap;
    }

    private List<Map<String, Object>> parseFinishedProductCode(PartBomTree partBomTree) {
        List<Map<String, Object>> itemMapList = new ArrayList<>();
        PartDetailsVO partDetailsVO = this.typlmPartService.queryPartDetails(new BigInteger(partBomTree.getPartoid()), partBomTree.getPartotype());
        Map<String, List<String>> ibaAttributeMap = partDetailsVO.getIbaAttributeMap();
        String devCode = ibaAttributeMap.get(RTPlmConstant.DevelopmentOrder).get(0);
        boolean isZ = devCode.startsWith("Z");

        if (!isZ) {
            // 如果不是 Z 开头，则为机组成品码
            itemMapList.addAll(buildNonZFinishedProductMap(partDetailsVO, ibaAttributeMap, devCode, isZ));
        } else {
            // 如果是 Z 开头，则为 动力的成品码
            List<String> currentFactories = ibaAttributeMap.get("factory");
            if (currentFactories != null && !currentFactories.isEmpty()) {
                for (String currentFactory : currentFactories) {
                    Map<String, Object> itemMap = createBaseItemMap(partDetailsVO, ibaAttributeMap, devCode);
                    setGraphicDocumentStatus(itemMap, ibaAttributeMap);
                    handleFactoryComparison(itemMapList, itemMap, currentFactory);
                }
            }
        }
        return itemMapList;
    }

    /**
     * 创建基础的 itemMap
     *
     * @param partDetailsVO   物料详情
     * @param ibaAttributeMap 扩展属性
     * @param devCode         开发令
     * @return 基础的 itemMap
     */
    private Map<String, Object> createBaseItemMap(PartDetailsVO partDetailsVO, Map<String, List<String>> ibaAttributeMap, String devCode) {
        Map<String, Object> itemMap = new HashMap<>();
        itemMap.put("ZKFL", devCode);
        itemMap.put("MATNR", partDetailsVO.getObjectNumber());
        itemMap.put("MAKTX", partDetailsVO.getName());
        itemMap.put("MTART", "Z001");
        itemMap.put("MTBEZ", "成品");
        itemMap.put("MEINS", "PC");
        itemMap.put("GEWEI", "KG");
        itemMap.put("VOLEH", "M3");
        itemMap.put("ZMAKTX", partDetailsVO.getDescription() != null ? partDetailsVO.getDescription() : "");
        putValueIfNotEmpty(itemMap, "ZJX", ibaAttributeMap.get("productType"));
        putValueIfNotEmpty(itemMap, "BISMT", ibaAttributeMap.get("oldMaterialCode"));
        putValueIfNotEmpty(itemMap, "ZJXHB", ibaAttributeMap.get("MechanicalEnvirCode"));
        return itemMap;
    }

    /**
     * 设置图形文档状态
     *
     * @param itemMap         存储结果的 map
     * @param ibaAttributeMap 扩展属性
     */
    private void setGraphicDocumentStatus(Map<String, Object> itemMap, Map<String, List<String>> ibaAttributeMap) {
        //获取ebom号的属性
        List<String> ebomCode = ibaAttributeMap.get("EBOMCode");
        if (ebomCode != null && !ebomCode.isEmpty()) {
            PartDetailsVO ebomPartDetail = queryAttributeOfDrawingCode(ebomCode.get(0));
            if (ebomPartDetail != null) {
                boolean graphicDocuments = checkIfThereAreAnyGraphicDocuments(new BigInteger(ebomPartDetail.getOid()));
                itemMap.put("ZSJTZ", graphicDocuments ? "Y" : "N");
            }
        }
    }

    /**
     * 处理工厂比较逻辑
     *
     * @param itemMapList    存储结果的列表
     * @param itemMap        存储结果的 map
     * @param currentFactory 当前工厂
     */
    private void handleFactoryComparison(List<Map<String, Object>> itemMapList, Map<String, Object> itemMap, String currentFactory) {
        if (StringUtils.isBlank(WERKS)) {
            // 第一个 Map，使用动力工厂 顶层为动力成品码
            itemMap.put("BESKZ", "E");
            itemMap.put("ZCPLB", "1");
            itemMap.put("WERKS", currentFactory);
            itemMapList.add(itemMap);
        } else {
            if (WERKS.equals(currentFactory)) {
                //顶层为机组成品码
                // 如果相同，则直接添加
                itemMap.put("BESKZ", "E");
                itemMap.put("ZCPLB", "2");
                itemMap.put("WERKS", currentFactory);
                itemMapList.add(itemMap);
            } else {
                // 如果机组和动力工厂不同 那么动力成品码除了传输生产工厂外,还要传输一条和机组生产工厂相同采购属性为F采购的数据
                // 第一个 Map，使用动力工厂
                itemMap.put("BESKZ", "E");
                itemMap.put("ZCPLB", "1");
                itemMap.put("WERKS", currentFactory);
                itemMapList.add(itemMap);

                // 第二个 Map，使用机组成品码工厂
                Map<String, Object> additionalItemMap = new HashMap<>(itemMap);
                additionalItemMap.put("BESKZ", "F");
                additionalItemMap.put("WERKS", WERKS);
                additionalItemMap.put("ZCPLB", "1");
                itemMapList.add(additionalItemMap);
            }
        }
    }

    /**
     * @param partDetailsVO   物料详情
     * @param ibaAttributeMap 扩展属性
     * @param devCode         开发令
     * @param isZ             是否为 Z 开头
     * @return 包含物料信息的 Map 列表
     */
    private List<Map<String, Object>> buildNonZFinishedProductMap(PartDetailsVO partDetailsVO, Map<String, List<String>> ibaAttributeMap, String devCode, boolean isZ) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        Map<String, Object> itemMap = createBaseItemMap(partDetailsVO, ibaAttributeMap, devCode);
        setGraphicDocumentStatus(itemMap, ibaAttributeMap);

        if (!isZ) {
            // 因为显示是非 Z 开头, 机组成品码为自制，设置成品类别为 3
            itemMap.put("BESKZ", "E");
            itemMap.put("ZCPLB", "3");
            // 记录 机组工厂为全局变量
            String factory = ibaAttributeMap.get("factory").get(0);
            itemMap.put("WERKS", factory);
            WERKS = factory;
            resultList.add(itemMap);
        } else {
            // 如果是 Z 开头，则为 动力的成品码
            String currentFactory = partDetailsVO.getView();
//            handleFactoryComparison(resultList, itemMap, currentFactory);
        }
        return resultList;
    }

    private String extractBaseObjectNumber(String objectNumber) {
        int lastIndex = objectNumber.lastIndexOf('-');
        return lastIndex != -1 ? objectNumber.substring(0, lastIndex) : objectNumber;
    }

    private PartDetailsVO queryAttributeOfDrawingCode(String baseObjectNumber) {
        // 查询关键字 16750-YJ30111
        SearchConditionDTO searchConditionDTO = new SearchConditionDTO();
        // 设置为不模糊匹配
        searchConditionDTO.setPreBlur(false);
        searchConditionDTO.setKeyword(baseObjectNumber);
        PageInfo<ResultEntityVO> resultEntityVOPageInfo = typlmCommonSearchService.queryByConditionForPage(searchConditionDTO);
        List<ResultEntityVO> collect = resultEntityVOPageInfo.getList().stream().filter(resultEntityVO -> baseObjectNumber.equals(resultEntityVO.getObjectNumber())&&resultEntityVO.getOtype().equals("ty.inteplm.part.CTyPart")).collect(Collectors.toList());
        // 简化条件判断
        if (!collect.isEmpty()) {
            BigInteger oid = collect.get(0).getOid();
            String otype = collect.get(0).getOtype();
            PartDetailsVO detailsVO = typlmPartService.queryPartDetails(oid, otype);
            return detailsVO;
        }
        return null;
    }

    /**
     * 如果列表不为空，则将列表的第一个元素放入 map 中
     *
     * @param map  存储结果的 map
     * @param key  map 的键
     * @param list 待检查的列表
     */
    private void putValueIfNotEmpty(Map<String, Object> map, String key, List<String> list) {
        if (list != null && !list.isEmpty()) {
            map.put(key, list.get(0));
        } else {
            map.put(key, "");
        }
    }

    private boolean checkIfThereAreAnyGraphicDocuments(BigInteger oid) {
        List<DocDetails> docDetails = typlmPartRelObjectService.queryPartRelatedDocInfo(oid);
        return docDetails != null && !docDetails.isEmpty();
    }

    // 修改返回类型为 List<Map<String, Object>>
    private List<Map<String, Object>> TraverseTheBOMTree(String oid, String otype, String viewName) {
        List<Map<String, PartDetailsVO>> list = queryChildPart(new ArrayList<>(), oid, otype, viewName);
        // 判断这个成品码是否是机组还是动力，通过开发开发令对的开头是否是 Z 来判断
        PartDetailsVO partDetailsVO = this.typlmPartService.queryPartDetails(new BigInteger(oid), otype);
        // 移除未使用的 isZ 变量
        return processPartBomTree(list);
    }

    // 移除未使用的参数 isZ
    private List<Map<String, Object>> processPartBomTree(List<Map<String, PartDetailsVO>> list) {
        List<Map<String, Object>> itemList = new ArrayList<>();
        if (list == null || list.isEmpty()) {
            return itemList;
        }
        String currentPosnr = "0010"; // 初始行号
        String lastMatnr = null; // 记录上一个成品码
        List<String> lastFactories = null; // 记录上一个成品码对应的工厂列表

        for (Map<String, PartDetailsVO> map : list) {
            Map<String, Object> itemMap = new HashMap<>();
            PartDetailsVO parentDetailsVO = map.get("parent");
            String parentOid = parentDetailsVO.getOid();
            // 成品码
            String matnr = parentDetailsVO.getObjectNumber();
            // 获取当前成品码对应的工厂信息列表
            List<String> factories =  Arrays.asList(parentDetailsVO.getView());
            // 若成品码改变，重置行号并更新工厂信息
            if (!Objects.equals(lastMatnr, matnr)) {
                currentPosnr = "0010";
                lastMatnr = matnr;
                lastFactories = factories; // 更新工厂信息列表
            }
            // 处理每个工厂信息
            if (lastFactories != null) {
                for (String factory : lastFactories) {
                    // 复制 itemMap 以避免不同工厂使用相同的 map 实例
                    Map<String, Object> factoryItemMap = new HashMap<>(itemMap);
                    factoryItemMap.put("WERKS", factory);
                    factoryItemMap.put("MATNR", matnr);
                    // 子物料编码
                    PartDetailsVO childDetailsVO = map.get("child");
                    // 查询父子关系
                    String childMasterOid = childDetailsVO.getMasteredoid();
                    List<PartUsageLink> linkDOS =rtChangeMapper.queryPartUsageLinkInfo(parentOid, childMasterOid);
                    if (CollUtil.isNotEmpty(linkDOS)) {
                        for (PartUsageLink partUsageLink:linkDOS){
                            Map<String, List<String>> ibaAttributeMap = partUsageLink.getIbaAttributeMap();
                            // 数量
                            factoryItemMap.put("MENGE", partUsageLink.getAmount() * 100);
                            // 子物料编码
                            factoryItemMap.put("IDNRK", childDetailsVO.getObjectNumber());
                            // 物料单位
                            factoryItemMap.put("MEINS", "PC");
                            // 段号
                            List<String> segmNum = ibaAttributeMap.get("SegmNum");
                            // 段号名称
                            List<String> position = ibaAttributeMap.get("Position");
                            if (segmNum != null && !segmNum.isEmpty() && position != null && !position.isEmpty()) {
                                factoryItemMap.put("POTX1", segmNum.get(0) + "|" + position.get(0));
                            }
                            // 行号
                            factoryItemMap.put("POSNR", currentPosnr);
                            itemList.add(factoryItemMap);
                        }
                    }
                }
            }
            // 生成下一个行号
            currentPosnr = generateNextPosnr(currentPosnr);
        }
        return itemList;
    }

    /**
     * 生成下一个 POSNR 值
     *
     * @param currentPosnr 当前的 POSNR 值
     * @return 下一个 POSNR 值
     */
    public static String generateNextPosnr(String currentPosnr) {
        int posnrValue = Integer.parseInt(currentPosnr);
        posnrValue += 10;
        // 格式化输出，不足 4 位时前面补 0
        return String.format("%04d", posnrValue);
    }

    /**
     * 获取sap中的项目令号
     * @param json
     * @return
     */
    @Override
    public JSONArray getSapProjectCode(JSONObject json){
        JSONObject params = new JSONObject();
        params.put("ET_TAB", "");
        String responseData = commonService.sendPostRequest(sapDevCodeUrl, sapName, sapPassword, params.toJSONString());
        JSONObject responseJson = JSONObject.parseObject(responseData);
        JSONObject tab = responseJson.getJSONObject("ET_TAB");
        JSONArray data = tab.getJSONArray("item");
        return data;
    }
}